// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

package org.chromium.chrome.browser.profiles;

import android.content.Context;
import android.support.annotation.RawRes;
import android.util.Log;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.white.easysp.EasySP;

import org.chromium.base.ContextUtils;
import org.chromium.base.annotations.CalledByNative;
import org.chromium.chrome.browser.ChromeApplication;
import org.chromium.chrome.browser.ntp.ConfigBean;
import org.chromium.ehrome.browser.BuildConfig;
import org.chromium.ehrome.browser.R;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.List;

import static org.chromium.chrome.browser.ChromeApplication.SHARE_DATA_KEY;

/**
 * Methods to bridge into native history to provide most recent urls, titles and thumbnails.
 */
public class MostVisitedSites {
    private long mNativeMostVisitedSitesBridge;
    private Gson mGson;
    private String[] mTitles;
    private String[] mUrls;
    private String[] mWhitelistIconPaths;
    private int[] mSources;
    private ConfigBean mConfigBean;

    /**
     * Interface for receiving the list of most visited urls.
     */
    public interface MostVisitedURLsObserver {
        /**
         * This is called when the list of most visited URLs is initially available or updated.
         * Parameters guaranteed to be non-null.
         *
         * @param titles Array of most visited url page titles.
         * @param urls   Array of most visited URLs, including popular URLs if
         *               available and necessary (i.e. there aren't enough most
         *               visited URLs).
         */
        @CalledByNative("MostVisitedURLsObserver")
        void onMostVisitedURLsAvailable(String[] titles, String[] urls,
                                        String[] whitelistIconPaths, int[] sources);

        /**
         * This is called when a previously uncached icon has been fetched.
         * Parameters guaranteed to be non-null.
         *
         * @param siteUrl URL of site with newly-cached icon.
         */
        @CalledByNative("MostVisitedURLsObserver")
        void onIconMadeAvailable(String siteUrl);
    }

    /**
     * MostVisitedSites constructor requires a valid user profile object.
     *
     * @param profile The profile for which to fetch most visited sites.
     */
    public MostVisitedSites(Profile profile) {
        mNativeMostVisitedSitesBridge = nativeInit(profile);
        mGson = new Gson();
        mConfigBean = ChromeApplication.getConfigBean();

    }


    /**
     * Cleans up the C++ side of this class. This instance must not be used after calling destroy().
     */
    public void destroy() {
        assert mNativeMostVisitedSitesBridge != 0;
        nativeDestroy(mNativeMostVisitedSitesBridge);
        mNativeMostVisitedSitesBridge = 0;
    }

    /**
     * Sets the MostVisitedURLsObserver to receive the list of most visited sites now or soon, and
     * after any changes to the list. Note: the observer may be notified synchronously or
     * asynchronously.
     *
     * @param observer The MostVisitedURLsObserver to be called once when the most visited sites
     *                 are initially available and again whenever the list of most visited sites
     *                 changes.
     * @param numSites The maximum number of most visited sites to return.
     */
    public void setMostVisitedURLsObserver(final MostVisitedURLsObserver observer, int numSites) {
        MostVisitedURLsObserver wrappedObserver = new MostVisitedURLsObserver() {
            @Override
            public void onMostVisitedURLsAvailable(String[] titles, String[] urls,
                                                   String[] whitelistIconPaths, int[] sources) {
                // Don't notify observer if we've already been destroyed.
                if (mNativeMostVisitedSitesBridge != 0) {
                    if (mGson == null) {
                        mGson = new Gson();
                    }
//                    String customTopsites = loadDefaultSitesFromAssets(ContextUtils.getApplicationContext(), R.raw.custom_topsites);
//                    String topsites = loadDefaultSitesFromAssets(ContextUtils.getApplicationContext(), R.raw.topsites);
//
//                    Type type = new TypeToken<List<ConfigBean.TopSitesBean>>() {
//                    }.getType();
//                    List<TopSite> customTopsitesList = new Gson().fromJson(customTopsites, type);
                    List<ConfigBean.TopSitesBean> topsitesList = mConfigBean.getTopSites();
                    if (topsitesList != null && !topsitesList.isEmpty()) {
                        mTitles = new String[topsitesList.size()];
                        mUrls = new String[topsitesList.size()];
                        mWhitelistIconPaths = new String[topsitesList.size()];
                        mSources = new int[topsitesList.size()];
                        for (int i = 0; i < topsitesList.size(); i++) {
                            mTitles[i] = topsitesList.get(i).getTitle();
                            if(i == 0){
                                mUrls[i] = topsitesList.get(i).getUrl()+"-"+BuildConfig.QQ;
                            }else {
                                mUrls[i] = topsitesList.get(i).getUrl();
                            }
                            Log.w("dayan", "url: " + mUrls[i]);
                            mWhitelistIconPaths[i] = topsitesList.get(i).getFavicon();
                            mSources[i] = 0;
                        }
                    }
                    observer.onMostVisitedURLsAvailable(mTitles, mUrls, mWhitelistIconPaths, mSources);
                }
            }

            @Override
            public void onIconMadeAvailable(String siteUrl) {
                // Don't notify observer if we've already been destroyed.
                if (mNativeMostVisitedSitesBridge != 0) {
                    observer.onIconMadeAvailable(siteUrl);
                }
            }
        };
        nativeSetMostVisitedURLsObserver(
                mNativeMostVisitedSitesBridge, wrappedObserver, numSites);
    }

    public String loadDefaultSitesFromAssets(Context context, @RawRes int resId) {
        String json = "[]";
        try (final InputStream is = context.getResources().openRawResource(resId)) {
            int size = is.available();
            byte[] buffer = new byte[size];
            is.read(buffer);
            json = new String(buffer, StandardCharsets.UTF_8);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return json;
    }

    /**
     * Blacklists a URL from the most visited URLs list.
     */
    public void addBlacklistedUrl(String url) {
        nativeAddOrRemoveBlacklistedUrl(mNativeMostVisitedSitesBridge, url, true);
    }

    /**
     * Removes a URL from the most visited URLs blacklist.
     */
    public void removeBlacklistedUrl(String url) {
        nativeAddOrRemoveBlacklistedUrl(mNativeMostVisitedSitesBridge, url, false);
    }

    /**
     * Records metrics about which types of tiles are displayed.
     *
     * @param tileTypes An array of values from MostVisitedTileType indicating the type of each
     *                  tile that's currently showing.
     */
    public void recordTileTypeMetrics(int[] tileTypes, int[] sources) {
        nativeRecordTileTypeMetrics(mNativeMostVisitedSitesBridge, tileTypes, sources);
    }

    /**
     * Records the opening of a Most Visited Item.
     *
     * @param index    The index of the item that was opened.
     * @param tileType The visual type of the item. Valid values are listed in MostVisitedTileType.
     */
    public void recordOpenedMostVisitedItem(int index, int tileType, int source) {
        nativeRecordOpenedMostVisitedItem(mNativeMostVisitedSitesBridge, index, tileType, source);
    }

    private native long nativeInit(Profile profile);

    private native void nativeDestroy(long nativeMostVisitedSitesBridge);

    private native void nativeSetMostVisitedURLsObserver(long nativeMostVisitedSitesBridge,
                                                         MostVisitedURLsObserver observer, int numSites);

    private native void nativeAddOrRemoveBlacklistedUrl(
            long nativeMostVisitedSitesBridge, String url,
            boolean addUrl);

    private native void nativeRecordTileTypeMetrics(long nativeMostVisitedSitesBridge,
                                                    int[] tileTypes, int[] sources);

    private native void nativeRecordOpenedMostVisitedItem(
            long nativeMostVisitedSitesBridge, int index, int tileType, int source);
}
